﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;
using ajayumi.develop.win32.Transport.Utils;

namespace ajayumi.develop.win32.Transport.AppUpgrade
{
    /// <summary>
    /// AppFileHelper.cs 应用程序文件操作辅助类
    /// Author   : 黄乙冬
    /// Date     : 2011-10-26
    /// </summary>
    public class AppFileHelper
    {
        #region Properties

        /// <summary>
        /// 应用程序文件夹
        /// </summary>
        public string AppDirectory { get; private set; }

        /// <summary>
        /// 更新文件所在文件夹
        /// </summary>
        public string UpgradeDir { get; private set; }

        /// <summary>
        /// 备份文件所存放的文件夹
        /// </summary>
        public string BackupDir
        {
            get { return Path.Combine(this.AppDirectory, Utility.BACKUP_FILE_NAME); }
        }

        #endregion

        public AppFileHelper(string appDir)
        { this.AppDirectory = appDir; }



        /// <summary>
        /// 升级应用程序
        /// </summary>
        /// <param name="upgradeDir"></param>
        /// <param name="appDir"></param>
        /// <returns></returns>
        internal bool UpgradeApp(string upgradeDir)
        {
            this.UpgradeDir = upgradeDir;

            try
            {
                if (Directory.Exists(this.BackupDir))
                { Directory.Delete(this.BackupDir, true); }

                // 备份
                string[] sourceFiles = FileHelper.GetSubFiles(this.AppDirectory);

                IEnumerable<string> backupFiles = from file in sourceFiles
                                                  where !file.Contains(this.UpgradeDir)
                                                  select file;
                this.CopyTo(backupFiles, AppFileAction.BackupFile);


                // 更新
                string[] upgradeFiles = FileHelper.GetSubFiles(this.UpgradeDir);
                this.CopyTo(upgradeFiles, AppFileAction.UpdateFile);

                try
                {
                    // 删除更新文件
                    if (Directory.Exists(this.UpgradeDir))
                    { Directory.Delete(this.UpgradeDir, true); }
                }
                catch (Exception)
                {
                }

                return true;
            }
            catch (Exception ex)
            {
                throw ex;
                return false;
            }
        }

        /// <summary>
        /// 还原应用程序
        /// </summary>
        /// <param name="appDir"></param>
        /// <returns></returns>
        internal bool RestoreApp()
        {
            try
            {
                if (Directory.Exists(this.BackupDir))
                {
                    // 备份
                    string[] backupFiles = FileHelper.GetSubFiles(this.BackupDir);

                    this.CopyTo(backupFiles, AppFileAction.RestoreFile);

                    try
                    {
                        // 删除备份文件
                        Directory.Delete(this.BackupDir, true);
                    }
                    catch (Exception)
                    {
                    }

                    return true;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return false;
        }

        private void CopyTo(IEnumerable<string> files, AppFileAction action)
        {
            int index = 0;
            int length = files.Count();

            foreach (string item in files)
            {
                string path = string.Empty;
                switch (action)
                {
                    case AppFileAction.RestoreFile:
                        path = item.Replace(this.BackupDir, this.AppDirectory);
                        break;
                    case AppFileAction.BackupFile:
                        path = item.Replace(this.AppDirectory, this.BackupDir);
                        break;
                    case AppFileAction.UpdateFile:
                        path = item.Replace(this.UpgradeDir, this.AppDirectory);
                        break;
                }

                FileHelper.CreateDir(path);
                File.Copy(item, path, true);

                int progressPercentage = Convert.ToInt32(Convert.ToSingle(++index) / Convert.ToSingle(length) * 100f);
                this.OnUpgradeProgressChanged(new UpgradeProgressChangedEventArgs(action, progressPercentage, this));
            }
        }

        private EventHandler<UpgradeProgressChangedEventArgs> m_UpgradeProgressChanged;
        public event EventHandler<UpgradeProgressChangedEventArgs> UpgradeProgressChanged
        {
            add { this.m_UpgradeProgressChanged = value; }
            remove { this.m_UpgradeProgressChanged -= value; }
        }
        protected virtual void OnUpgradeProgressChanged(UpgradeProgressChangedEventArgs e)
        {
            if (this.m_UpgradeProgressChanged != null)
            { this.m_UpgradeProgressChanged(this, e); }
        }

    }
}
